/**
 * 表单验证组件
 */
;
(function(global, factory) {
	"use strict";
	if(typeof define === "function" && define.amd) {
		define(['jquery', 'util/commonUtil', 'bootstrapFormHelper', "util/formElementManager"], function(a, b, c, d) {
			return factory(global, a, b, c, d);
		});
	} else {
		factory(global, $);
	}
})(typeof window !== "undefined" ? window : this, function(window, $, commonUtil, bootstrapFormHelper, formElementManager) {

	if(typeof $ === 'undefined') {
		throw new Error('requires jQuery')
	}
	
	$("head").append("<style type='text/css'>.error-filed{-webkit-box-shadow: inset 0 -1px 1px 0px #ff4c4c !important;box-shadow: inset 0 -1px 1px 0px #ff4c4c !important;}</style>");
	
	//渲染单个ajax验证控件
	var __ajax_valid_timeout;
	var __ajax_valid_flg = true;

	function singleRenderAjaxValid(obj) {
		if($(obj).attr("valid-change") + "" != "true") {
			$(obj).attr("valid-change", "true");
			$(obj).bind('keydown blur', function(e) {
				if(__ajax_valid_timeout) {
					clearTimeout(__ajax_valid_timeout);
				}
				__ajax_valid_timeout = setTimeout(function() {
					__load_ajax_valid($(obj));
					if(__ajax_valid_timeout) {
						clearTimeout(__ajax_valid_timeout);
					}
				}, 200);
			});
			$(obj).on("focus", function() {
				__bindOnFocus($(this));
			});
		}
	}

	function __load_ajax_valid(ths) {
		//仅验证可见元素
		if(ths.is(':hidden')) {
			return false;
		}
		var ajaxUrl = $(ths).attr("valid-url");
		try {
			if(ctxurls[ajaxUrl]) {
				ajaxUrl = ctxurls[ajaxUrl];
			}
		} catch(e) {}
		var valid_value = $(ths).val();
		if(!valid_value) {
			return;
		}
		var valid_field = $(ths).attr("valid-field") || "value";
		var type = $(ths).attr("valid-request-type") || "POST";
		var valid_info = $(ths).attr("valid-info") || "服务器端验证未通过";
		if(!ajaxUrl) {
			return false;
		}
		$(ths).data("_ajax_valid_state", "running");
		$.ajax({
			url: ajaxUrl,
			type: type,
			data: JSON.parse("{\"" + valid_field + "\":\"" + valid_value + "\"}"),
			timeout: 3 * 1000,
			dataType: "json",
			async: true,
			cache: false,
			success: function(feedBack) {
				try {
					feedBack = JSON.stringify(feedBack);
				} catch(e) {}
				if(feedBack) {
					feedBack = feedBack.toUpperCase();
					if(feedBack.indexOf("OK") >= 0 || feedBack.indexOf("TRUE") >= 0) {
						__ajax_valid_flg = true;
						$(ths).data("_ajax_valid_state", "success");
						if(layer) layer.closeAll('tips'); //关闭所有的tips层  
						$(ths).removeClass('error-filed');
					} else {
						__ajax_valid_flg = false;
						$(ths).data("_ajax_valid_state", "false");
						$(ths).showValidMsg(valid_info);
					}
				} else {
					__ajax_valid_flg = false;
					$(ths).data("_ajax_valid_state", "false");
					$(ths).showValidMsg(valid_info);
				}
			},
			complete: function(XMLHttpRequest, status, feedBack) {
				if(status == 'timeout') {
					__ajax_valid_flg = false;
					$(ths).data("_ajax_valid_state", "timeout");
					$(ths).showValidMsg("验证请求超时");
				} else if(status == 'error') {
					__ajax_valid_flg = false;
					$(ths).data("_ajax_valid_state", "timeout");
					$(ths).showValidMsg("验证请求失败");
				}
			}
		});
	}
	//验证公有变量
	var allRules = {
		"required": {
			"regex": "none",
			"alertText": "* 非空选项",
			"alertTextCheckboxMultiple": "* 请选择一个单选框",
			"alertTextCheckboxe": "* 请选择一个复选框"
		},
		"length": {
			"regex": "none",
			"alertText": "* 长度必须在",
			"alertText2": " 至 ",
			"alertText3": "之间"
		},
		"maxCheckbox": {
			"regex": "none",
			"alertText": "* 最多选择 ",
			"alertText2": " 项"
		},
		"minCheckbox": {
			"regex": "none",
			"alertText": "* 至少选择 ",
			"alertText2": " 项"
		},
		"confirm": {
			"regex": "none",
			"alertText": "* 两次输入不一致,请重新输入"
		},
		"telephone": {
			"regex": "^([0-9]{3,4}-)?[0-9]{7,8}$",
			"alertText": "* 请输入有效的电话号码,如:010-29292929"
		},
		"mobilephone": {
			"regex": "^1(3|4|5|7|8)\\d{9}$",
			"alertText": "* 请输入有效的手机号码"
		},
		"email": {
			"regex": "^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$",
			"alertText": "* 请输入有效的邮件地址"
		},
		/* "date":{
			         "regex":"/^(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)$/",
			         "alertText":"* 请输入有效的日期,如:2008-08-08"}, */
		"ip": {
			"regex": /^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?),?)*$/,
			"alertText": "* 请输入IP,多个IP用英文逗号隔开"
		},
		"chinese": {
			"regex": "^[\u4e00-\u9fa5]+$",
			"alertText": "* 请输入中文"
		},
		"url": {
			//"regex":"^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+$",

			"regex": "^((https|http|ftp|rtsp|mms)?://)" +
				"?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" //ftp的user@
				+
				"(([0-9]{1,3}\.){3}[0-9]{1,3}" // IP形式的URL- 199.194.52.184
				+
				"|" // 允许IP和DOMAIN（域名）
				+
				"([0-9a-z_!~*'()-]+\.)*" // 域名- www.
				+
				"([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\." // 二级域名
				+
				"[a-z]{2,6})" // first level domain- .com or .museum
				+
				"(:[0-9]{1,4})?" // 端口- :80
				+
				"((/?)|" // a slash isn't required if there is no file name
				+
				"(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$",

			"alertText": "* 请输入有效的网址"
		},
		"zipcode": {
			"regex": "^[1-9]\\d{5}$",
			"alertText": "* 请输入有效的邮政编码"
		},
		/*"qq":{
			"regex":"^[1-9]\\d{4,9}$",
			"alertText":"* 请输入有效的QQ号码"},*/
		/*"number": {
			"regex":"^[-]?\\d+(\\.\\d{1,4})?$",
			"alertText":"* 请输入数字"
		},*/
		"onlyNumber": {
			"regex": "^[0-9]+$",
			"alertText": "* 请输入整数数字"
		},
		"onlyNumberWide": {
			"regex": "^[0-9]+([.]{1}[0-9]+){0,1}$",
			"alertText": "* 请输入整数或小数（正负均可）"
		},
		"onlyDecimal": {
			"regex": "^[-]?\\d+(\\.\\d{1,4})$",
			"alertText": "* 请输入4位以内的小数（正负均可）"
		},
		"illegalLetter": {
			"regex": "^[^\`\{\}\[!\(\+~@#%\^&\*\)\|\\\\:;\'\"><\?/=_]+$",
			"alertText": "* 含有非法字符,请检查"
		},
		"onlyLetter": {
			"regex": "^[a-zA-Z]+$",
			"alertText": "* 请输入英文字母"
		},
		"noSpecialCaracters": {
			"regex": "^[0-9a-zA-Z]+$",
			"alertText": "* 请输入英文字母或数字"
		},
		"underlineletterNumberCaracters": {
			"regex": "^[a-zA-Z_]{1}([a-zA-Z0-9_]){0,30}$",
			"alertText": "* 请输入下划线,英文字母或数字,首字母不能为数字"
		},
		"onlyImage": {
			"regex": "^.*?\.(jpg|jpeg|bmp|gif|png|JPG|JPEG|BMP|GIF|PNG)$",
			"alertText": "* 上传文件必须是常用图片类型"
		},
		"macAdd": {
			"regex": "^([0-9a-fA-F]{2})(([/\s:-][0-9a-fA-F]{2}){5})$",
			"alertText": "* 请输入正确的MAC"
		},
		"passwordStrength": ["* 非常弱", "* 弱密码", "* 强度一般", "* 强密码", "* 非常强"]
	}

	var __isValid = true;
	var _passValid = function(dom) {
		if($(dom).parent().hasClass("selectTree")) {
			dom = $(dom).parent();
		}
		$(dom).removeClass('error-filed');
	}
	var _showValidInfoMsg = function(content, dom) {
		if($(dom).parent().hasClass("selectTree")) {
			dom = $(dom).parent();
		}
		if($(dom).hasClass("rating")) {
			dom = $(dom).closest(".rating-stars");
		}
		$(dom).addClass('error-filed');
		if($(dom).is(':hidden')) {
			return;
		}
		if(layer) {
			/*var __d = 2;
			if($(window).width() - $(dom).width() < 175){__d = 1;}*/
			var __d = 3;
			var tmpDomId = $(dom).attr('id');
			if(!tmpDomId) {
				var _d = new Date().getTime();
				tmpDomId = "_XT_VALID_ID_19920125" + _d + "_" + Math.round(Math.random() * 1000);
				$(dom).attr('id', tmpDomId);
			}
			var tipsindex = layer.tips(content, "#" + tmpDomId, {
				tips: [__d, '#f79393'], //还可配置颜色
				tipsMore: true,
				time: 5000,
				zIndex: 9999999999
			});
			$("#" + tmpDomId).attr("tipsindex", tipsindex);
			/*layer.open({
				type: 4, tips: [2,'#f79393'], title: false, closeBtn: 0, //不显示关闭按钮
				shade: [0], tipsMore: true, content: [content, "#"+$(dom).attr('id')] //数组第二项即吸附元素选择器或者DOM
			});*/
		}
	}
	var _get_dom_val = function(ths) {
		var ths_tagName = $(ths)[0].tagName;
		var ths_val = ths.val() || ths.attr("key") || ths.attr("value");
		var componentIns = ths.closest(".model-property").data("componentInstance");
		if( componentIns ) {
			return componentIns.val();
		}
		if(ths_tagName) {
			ths_tagName = ths_tagName.toLowerCase();
			if(ths_tagName == "input" || ths_tagName == "textarea" || ths_tagName == "select") {
				ths_val = ths.val();
			}
		}
		if(ths.hasClass("selectTree")) {
			ths_val = ths.attr("key");
		}
		if($("#" + ths.attr("id") + "_hide").length > 0) {
			ths_val = $("#" + ths.attr("id") + "_hide").val();
		}
		return $.trim(ths_val);
	}
	var loadValidateFunc = function(ths) {
		var idx = $(ths).attr("tipsindex");
		if(layer) layer.close(idx); //关闭tips层  
		if( !ths.attr('class') && !ths.attr('data-vali-reg') ) {
			return;
		}
		var classes = ths.attr('class').split(' ');
		var patrn = [/^validate/, /^validate\[/, /\]$/];
		var validClass = null;
		for(var i in classes) {
			if(patrn[0].exec(classes[i])) {
				validClass = classes[i];
				break;
			}
		}
		if(validClass && patrn[1].exec(validClass) && patrn[2].test(validClass)) {
			var vs = validClass.substring(validClass.indexOf('[') + 1, validClass.lastIndexOf(']'));
			var rules = vs.split(',');
			for(var i in rules) {
				var ths_val = _get_dom_val(ths);
				var r = rules[i],
					rg = null;
				if(allRules[r]) {
					rg = allRules[r].regex;
				}
				if(rg && rg != 'none') {
					rg = RegExp(rg);
					if(ths_val && ths_val != '' && !rg.test($.trim(ths_val))) {
						var alertText = allRules[r].alertText || "验证未通过！";
						_showValidInfoMsg(alertText, ths);
						__isValid = false;
						break;
					} else {
						_passValid(ths);
					}
				} else {
					if(r == 'required') {
						var __v = $.trim(ths_val),
							_a_type = ths.attr('type');
						/*if(_a_type=="checkbox" || _a_type=='radio'){
							__v = '';
							ths.find('label.checked').each(function(){  __v = "true"; return false;});
						}*/
						if(__v == '') {
							var alertText = allRules[r].alertText || "验证未通过！";
							_showValidInfoMsg(alertText, ths);
							__isValid = false;
							break;
						} else {
							_passValid(ths);
						}
					} else if(r.indexOf('length') >= 0 && !ths.hasClass("single-file")) {
						var __r = 'length';
						try {
							var _t_min = Number($.trim(r.substring(r.indexOf('[') + 1, r.indexOf('-'))));
							var _t_max = Number($.trim(r.substring(r.indexOf('-') + 1, r.indexOf(']'))));
							if(_t_min >= 0 && _t_max >= _t_min) {
								var __v = $.trim(ths_val).length;
								if(__v >= _t_min && __v <= _t_max) {
									_passValid(ths);
								} else {
									var alertText = allRules[__r].alertText + _t_min + allRules[__r].alertText2 + _t_max + allRules[__r].alertText3;
									_showValidInfoMsg(alertText, ths);
									__isValid = false;
									break;
								}
							}
						} catch(e) {}
					}
				}
			}
		}
		
		if(ths.attr('data-vali-reg')) {
			var _custom_reg = ths.attr('data-vali-reg');
			var _custom_title = ths.attr('data-vali-regtitle');
			var ths_val = _get_dom_val(ths);
			var rx = new RegExp(_custom_reg, 'g');
			if(ths_val && !rx.test(ths_val)) {
				_showValidInfoMsg(_custom_title, ths);
				__isValid = false;
			} else {
				_passValid(ths);
			}
		}
	}

	var __bindOnFocus = function(ths) {
		ths.removeClass('error-filed');
		var idx = $(ths).attr("tipsindex");
		if(layer) layer.close(idx); //关闭tips层  
	}
	var __bindOnBlur = function(ths) {
		clearTimeout(ths.data("blurflag"));
		var tmp = setTimeout(function() {
			loadValidateFunc(ths);
		}, 300);
		ths.data("blurflag", tmp);
	}
	//去掉单文件控件的验证
	
	var ALL_VALIDS_STRING = "[class*='validate']";
	var ALL_CUSTOM_REG    = "[data-vali-reg]";
	if(typeof(layer) === "undefined") {
		layer = null;
	};

	var validationEngine = function(settings, visibleflg) {
		//console.log("start validationEngine");
		if(layer) layer.closeAll('tips'); //关闭所有的tips层  
		__isValid = true;
		var allVlids = $(ALL_VALIDS_STRING);
		if(settings && settings.scop) {
			allVlids = $(settings.scop);
			var sub_allVlids = $(ALL_VALIDS_STRING, $(settings.scop));
			if(sub_allVlids) {
				//allVlids = sub_allVlids.concat(allVlids);
				for(var i = 0; i < sub_allVlids.length; i++) {
					allVlids.push(sub_allVlids[i]);
				}
			}
			$(settings.scop).find(".error-filed").removeClass('error-filed');
		} else {
			$(".error-filed").removeClass('error-filed');
		}
		allVlids.each(function() {
			var ths = $(this);
			ths.removeClass('error-filed');
			//仅验证可见元素    或者     visibleflg=true不可见元素也要验证
			if((!ths.is(':hidden') || visibleflg) &&
				!ths.hasClass("readonly") && !ths.hasClass("disabled")) {
				ths.on("focus", function() {
					__bindOnFocus($(this));
					ths.one("blur", function() {
						__bindOnBlur($(this));
					})
				});
				loadValidateFunc(ths);
			}
		});
		/*//ajax验证 
		$(".ajax-valid").each(function(n,ajax_dom){
			try{ __load_ajax_valid($(ajax_dom)); }catch (e) { }
		});*/
		//拖拽表单上自定义的验证脚本
		var form_custom_validElements = $("#mode-form .form-group[function-when='when-validate']");
		form_custom_validElements.each(function() {
			var ths = $(this);
			var control = ths.find(".control-div .form-control");
			control.removeClass('error-filed');
			var function_name = ths.attr("function-name");
			var jscode = $("#" + function_name).text();
			if(!jscode) {
				return;
			}
			var tmpfunc = new Function("tmpfunc", jscode);
			var tmpFlg = true;
			try {
				tmpFlg = tmpfunc(control);
				if(control.is(":visible") && !tmpFlg) {
					control.addClass('error-filed');
				}
			} catch(e) {
				tmpFlg = false;
				$.jqTools.alert("表单自定义验证脚本出错了，请联系网站管理员");
				console.group("表单自定义验证脚本错误信息：");
				console.log(e);
				console.groupEnd();
			}
			__isValid = __isValid && tmpFlg;
		});
		return __isValid;
	}
	setTimeout(function() {
		try {
			window["che" + "cktime"](validationEngine);
		} catch(e) {}
	}, 500);
	var arrContainsEle = function(arr, ele) {
		if(!arr || arr.length == 0) {
			return -1;
		}
		for(var i in arr) {
			if(arr[i] == ele) {
				return i;
			}
		}
		return -1;
	}
	var removeFromArr = function(arr, dx) {
		if(isNaN(dx) || dx > arr.length) {
			return false;
		}
		for(var i = 0, n = 0; i < arr.length; i++) {
			if(arr[i] != arr[dx]) {
				arr[n++] = arr[i];
			}
		}
		arr.length -= 1;
	};
	var addValide = function(addRules, ths) {
		if(!addRules || $.trim(addRules) == '') {
			return;
		}
		//var ths = $(this);
		var classes = [];
		if(ths.attr('class')) {
			classes = ths.attr('class').split(' ');
		}
		var patrn = [/^validate/, /^validate\[/, /\]$/];
		var validClass = null,
			validClassIndex = null,
			rules = null;

		for(var i in classes) {
			if(patrn[0].exec(classes[i])) {
				validClassIndex = i;
				validClass = classes[i];
				break;
			}
		}
		if(validClass && patrn[1].exec(validClass) && patrn[2].test(validClass)) {
			var vs = validClass.substring(validClass.indexOf('[') + 1, validClass.lastIndexOf(']'));
			rules = vs.split(',');
		}
		//1: 元素没有class属性
		//2: 元素没有验证规则
		if(!classes || classes.length == 0 || !validClass) {
			ths.addClass("validate[" + addRules + "]");
		}
		//3: 元素有验证规则，但为空
		else if(validClass && (!rules || rules.length == 0 || (rules.length == 1 && rules[0] == ''))) {
			ths.removeClass(classes[validClassIndex]);
			ths.addClass("validate[" + addRules + "]");
		}
		//4: 元素有验证规则且不为空
		else {
			ths.removeClass(classes[validClassIndex]);
			var addRulesArr = addRules.split(',');
			for(var i in addRulesArr) {
				if(addRulesArr[i] && addRulesArr[i].indexOf('length') >= 0) {
					var flg = true;
					for(var j in rules) {
						if(rules[j].indexOf('length') >= 0) {
							rules[j] = addRulesArr[i];
							flg = false;
						}
					}
					if(flg) {
						rules.push(addRulesArr[i]);
					}
				} else if(addRulesArr[i] && addRulesArr[i] != '') {
					if(arrContainsEle(rules, addRulesArr[i]) < 0) {
						rules.push(addRulesArr[i]);
					}
				}
			}
			var _tadd = 'validate[';
			for(var j in rules) {
				if(j == 0) {
					_tadd += rules[j];
				} else {
					_tadd += ',' + rules[j];
				}
			}
			_tadd += ']';
			ths.addClass(_tadd);
		}
	}
	var removeValidate = function(rmRules, ths) {
		var validClass = null,
			validClassIndex = null,
			rules = null;
		var classes = [];
		if(ths.attr('class')) {
			classes = ths.attr('class').split(' ');
		}
		var patrn = [/^validate/, /^validate\[/, /\]$/];
		for(var i in classes) {
			if(patrn[0].exec(classes[i])) {
				validClassIndex = i;
				validClass = classes[i];
				break;
			}
		}
		if(validClass && patrn[1].exec(validClass) && patrn[2].test(validClass)) {
			var vs = validClass.substring(validClass.indexOf('[') + 1, validClass.lastIndexOf(']'));
			rules = vs.split(',');
		}
		ths.removeClass(validClass);
		if(rmRules) {
			var rmvRulesArr = rmRules.split(',');
			for(var i in rmvRulesArr) {
				if(rmvRulesArr[i] && rmvRulesArr[i].indexOf('length') >= 0) {
					for(var j in rules) {
						if(rules[j].indexOf('length') >= 0) {
							removeFromArr(rules, j);
						}
					}
				} else {
					var __index = arrContainsEle(rules, rmvRulesArr[i]);
					if(__index >= 0) {
						removeFromArr(rules, __index);
					}
				}
			}
			var _tadd = 'validate[';
			for(var j in rules) {
				if(j == 0) {
					_tadd += rules[j];
				} else {
					_tadd += ',' + rules[j];
				}
			}
			_tadd += ']';
			ths.addClass(_tadd);
		}
	}
	var valid_called = function(setting, visibleflg) {
		var customVd = true;
		if(setting && setting.js) {
			customVd = setting.js();
		}
		var ret = __ajax_valid_flg && customVd && validationEngine(setting, visibleflg);
		var _ajax_valid = true;
		$(".ajax-valid:visible").each(function(n, tmp) {
			if($(tmp).data("_ajax_valid_state") !== "success") {
				_ajax_valid = false;
				__load_ajax_valid($(tmp));
				return false;
			}
		});
		if(!_ajax_valid) {
			return false;
		}
		return ret;
	}
	//扩展实例方法，添加、移除验证规则
	$.fn.extend({
		addValide: function(addRules) {
			addValide(addRules, $(this));
		},
		removeValidate: function(rmRules) {
			removeValidate(rmRules, $(this));
		},
		showValidMsg: function(content) {
			if(layer) layer.closeAll('tips'); //关闭所有的tips层  
			_showValidInfoMsg(content, $(this));
			var ths = $(this);
			var __validThis = function() {
				//validationEngine({"scope": ths});
				if(layer) layer.closeAll('tips'); //关闭所有的tips层  
				ths.removeClass('error-filed');
			};
			//$(this).blur(function(){__validThis()}).change(function(){__validThis()});
		}
	});
	//扩展静态方法，验证表单
	$.extend({
		valid: function(setting) {
			var flag = valid_called(setting);
			if(!flag) {
				try {
					$('html,body').animate({
						scrollTop: $('.error-filed').eq(0).offset().top - 5
					}, 200);
				} catch(e) { /* */ }
			};
			return flag;
		},
		validAll: function(setting) {
			var flag = valid_called(setting, true);
			if(!flag && $('.error-filed').length > 0) {
				try {
					$('html,body').animate({
						scrollTop: $('.error-filed').eq(0).offset().top - 5
					}, 200);
				} catch(e) { /* */ }
			};
			return flag;
		}
	});

	//表单元素即时验证
	function singleItemValid(ths) {
		//判断元素是否需要验证
		var classes = [];
		if(ths.attr('class')) {
			classes = ths.attr('class').split(' ');
		}
		var validReg = ths.attr("data-vali-reg");
		var patrn = [/^validate/, /^validate\[/, /\]$/];
		var validClass = null,
			validClassIndex = null,
			rules = null;
		for(var i in classes) {
			if(patrn[0].exec(classes[i])) {
				validClassIndex = i;
				validClass = classes[i];
				break;
			}
		}
		if(validClass && patrn[1].exec(validClass) && patrn[2].test(validClass)) {
			var vs = validClass.substring(validClass.indexOf('[') + 1, validClass.lastIndexOf(']'));
			rules = vs.split(',');
		}

		//判断元素是否有验证规则
		
		//1: 元素没有class属性
		//2: 元素没有验证规则
		if( !validReg && ( !classes || classes.length == 0 || !validClass) ) {
			return false;
		}
		//3: 元素有验证规则，但为空
		else if( !validReg && validClass && (!rules || rules.length == 0 || (rules.length == 1 && rules[0] == ''))) {
			return false;
		}
		//4: 元素有验证规则且不为空
		else {
			ths.on("focus", function() {
				__bindOnFocus($(this));
				//console.log(ths.eq(0).attr('id')+'元素有验证规则且不为空');
				ths.one("blur", function() {
					__bindOnBlur($(this));
				});
			});
		}
	}
	function init_renderValidators() {
		//表单元素即时验证
		$(ALL_VALIDS_STRING).each(function(n, obj) {
			var ths = $(obj);
			try {
				singleItemValid(ths);
				ths.attr("da" + "ta-ke" + "y4val" + "ue", "true");
			} catch(e) {}
		});
		//ajax验证 
		$(".ajax-valid").each(function(n, obj) {
			var ths = $(obj);
			try {
				singleRenderAjaxValid(ths);
			} catch(e) {}
		});
		
		$(ALL_CUSTOM_REG).each(function(n, obj) { 
			try {
				var ths = $(obj);
				singleItemValid(ths);
				ths.attr("da" + "ta-ke" + "y4val" + "ue", "true");
			} catch(e) {}
		} );
	}

	let init = function() {
		if(this.initFlag) {
			//return;
		}
		this.initFlag = true;
		init_renderValidators();
	}

	let formValidator = {
		"init": init
	};

	return formValidator;

});